/*
===========================================================================
This source file is part of DyLab (Dynamic Laboratory)
For the latest info, see http://dylab-modules.googlecode.com

Copyright (c) 2006-2008 Lukas Krejci
(krejci.lukas@volny.cz)

This file is part of DyLab.

    DyLab is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    DyLab is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with DyLab.  If not, see <http://www.gnu.org/licenses/>.
===========================================================================
*/

//===========================================================================================
#include "HotKeysHandler.h"

//===========================================================================================
const dylab::String dylab::HotKeysHandler::COMPONENT_NAME = "hotKeysHandler";

//===========================================================================================
dylab::HotKeysHandler::HotKeysHandler()
: ComEventListener(COMPONENT_NAME), mSimulation(NULL)
{
}
//-----------------------------------------------------------------------------
dylab::HotKeysHandler::~HotKeysHandler()
{
}
//-----------------------------------------------------------------------------
void dylab::HotKeysHandler::initialize(Simulation * _simulation)
{ 
    // store the simulation pointer
    mSimulation = _simulation; 

    // register our listener
    registerAsInputEventListener();
}
//-----------------------------------------------------------------------------
void dylab::HotKeysHandler::loadFromPropertyTree(const PropertyTree & _pt)
{
	const PropertyTree::Node * ptNode;

	if ((ptNode = _pt.findNode("quit")) != NULL)
        mActions.bindAction(InputEvent::str2KeyCode(ptNode->getValue()), &HotKeysHandler::onQuit);    
	if ((ptNode = _pt.findNode("speedUp")) != NULL)
        mActions.bindAction(InputEvent::str2KeyCode(ptNode->getValue()), &HotKeysHandler::onSpeedUp);    
	if ((ptNode = _pt.findNode("slowDown")) != NULL)
        mActions.bindAction(InputEvent::str2KeyCode(ptNode->getValue()), &HotKeysHandler::onSlowDown);    
	if ((ptNode = _pt.findNode("pause")) != NULL)
        mActions.bindAction(InputEvent::str2KeyCode(ptNode->getValue()), &HotKeysHandler::onPause);    
	if ((ptNode = _pt.findNode("polygonMode")) != NULL)
        mActions.bindAction(InputEvent::str2KeyCode(ptNode->getValue()), &HotKeysHandler::onPolygonMode);    
	if ((ptNode = _pt.findNode("gui")) != NULL)
        mActions.bindAction(InputEvent::str2KeyCode(ptNode->getValue()), &HotKeysHandler::onGUI);    
}
//-----------------------------------------------------------------------------
dylab::Simulation * dylab::HotKeysHandler::getParentSimulation()
{
    return mSimulation;
}
//-----------------------------------------------------------------------------
const dylab::Simulation * dylab::HotKeysHandler::getParentSimulation() const
{
    return mSimulation;
}
//-----------------------------------------------------------------------------
void dylab::HotKeysHandler::processEvent(const InputEvent & _inputEvent)
{           
    if (_inputEvent.getType() == InputEvent::KEY_UP)     
        mActions.trySignal(_inputEvent.getKeyCode(), this);    
}
//-----------------------------------------------------------------------------
void dylab::HotKeysHandler::onQuit()
{
    // terminate simulation (application)
    mSimulation->setQuitFlag();
}
//-----------------------------------------------------------------------------
void dylab::HotKeysHandler::onSpeedUp()
{
    // speed up simulation by increasing its time factor
	mSimulation->setTimeFactor(mSimulation->getTimeFactor() + DYLAB_R(0.1));

	DYLAB_LOGF("New simulation time factor: %1%", mSimulation->getTimeFactor());
}
//-----------------------------------------------------------------------------
void dylab::HotKeysHandler::onSlowDown()
{
	if (mSimulation->getTimeFactor() > DYLAB_R(0.15))
	{
	    // speed up simulation by decreasing its time factor
		mSimulation->setTimeFactor(mSimulation->getTimeFactor() - DYLAB_R(0.1));

		DYLAB_LOGF("New simulation time factor: %1%", mSimulation->getTimeFactor());
	}
}
//-----------------------------------------------------------------------------
void dylab::HotKeysHandler::onPause()
{
    // pause/resume simulation objects
	if (mSimulation->areSimObjectsPaused())
	{
		mSimulation->pauseSimObjects(false);
		DYLAB_LOG("Simulation resumed");
	}
	else
	{
		mSimulation->pauseSimObjects(true);
		DYLAB_LOG("Simulation paused");
	}
}
//-----------------------------------------------------------------------------
void dylab::HotKeysHandler::onPolygonMode()
{
    // toggle solid/wireframe camera polygon mode
    ComGfx::ICamera::ScopedExLock camera(mSimulation->getGfx());
    switch (camera->getPolygonMode())
    {
    case ComGfx::ICamera::SOLID:
        camera->setPolygonMode(ComGfx::ICamera::WIREFRAME);
        break;
    case ComGfx::ICamera::WIREFRAME:
        camera->setPolygonMode(ComGfx::ICamera::SOLID);
        break;
    }
}
//-----------------------------------------------------------------------------
void dylab::HotKeysHandler::onGUI()
{
    // show/hide info panels
    ComGfx::IGuiSystem::ScopedExLock guiSystem(mSimulation->getGfx());
    guiSystem->showGui("Core/DebugOverlay", !guiSystem->isGuiVisible("Core/DebugOverlay"));
}
//-----------------------------------------------------------------------------